package com.open.jack.jk_mpchart;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.github.mikephil.charting.utils.MPPointD;

import java.util.ArrayList;
import java.util.List;

/**
 * @TODO
 * @author: clf
 * @since: 2020/11/26
 */
public abstract class IotLineChart extends LineChart implements IChartBase {
    HighlightEntry minHighlight = null;
    HighlightEntry maxHighlight = null;
    public boolean showMinMAxHighlight = true;

    protected boolean mDrawAxisLeftGridInnerLines = false;
    protected MyYAxisRenderer iotYAxisRendererLeft ;
    public void setDrawAxisLeftGridInnerLines(boolean enabled) {
        mDrawAxisLeftGridInnerLines = enabled;
        iotYAxisRendererLeft.mDrawGridInnerLines = mDrawAxisLeftGridInnerLines;
    }

    @Override
    public void clear() {
        super.clear();
        highlightValues(null);
        if (showMinMAxHighlight){
            minHighlight = null;
            maxHighlight = null;
        }
    }

    public void addYLimitLine(float limit, String label,int lineColor,int textColor,boolean enableDashed) {
        LimitLine ll1 = new LimitLine(limit, label);
        ll1.setLineWidth(1f);
        if (enableDashed) {
            ll1.enableDashedLine(8f, 8f, 0f);
        }
        ll1.setLabelPosition(LimitLine.LimitLabelPosition.LEFT_TOP);
        ll1.setTextSize(8.67f);
        ll1.setLineColor(lineColor);
        ll1.setTextColor(textColor);
        getAxisLeft().addLimitLine(ll1);
    }

    @Override
    protected void init() {
        super.init();
        getDescription().setEnabled(false);
        mXAxis.setAvoidFirstLastClipping(true);

        //mXAxis.setAxisMinimum(0f);
        mXAxis.setPosition(XAxis.XAxisPosition.BOTTOM);

        mXAxisRenderer = new MyXAxisRenderer(mViewPortHandler, mXAxis, mLeftAxisTransformer);
        iotYAxisRendererLeft = new MyYAxisRenderer(mViewPortHandler, mAxisLeft, mLeftAxisTransformer);
        iotYAxisRendererLeft.mDrawGridInnerLines = mDrawAxisLeftGridInnerLines;

        mAxisRendererLeft = iotYAxisRendererLeft;
        //mAxisLeft.setAxisMinimum(0f); // this replaces setStartAtZero(true)

        mAxisRight.setEnabled(false);
        mLegend.setEnabled(false);

        setNoDataText(null);
    }



    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (showMinMAxHighlight){
            resetMinMaxHighlight();
        }
    }

    Highlight getHighlight(IDataSet set,Entry e, int dataSetIndex){
        MPPointD pixels = getTransformer(set.getAxisDependency()).getPixelForValues(e.getX(), e.getY());
        MPPointD pix = getTransformer(set.getAxisDependency()).getPixelForValues(e.getX(), e.getY() * mAnimator
                .getPhaseY());
        Highlight high =new Highlight(
                e.getX(), e.getY(),
                (float) pixels.x, (float) pixels.y,
                dataSetIndex, set.getAxisDependency());
        high.setDraw((float) pix.x, (float) pix.y);
        MPPointD.recycleInstance(pixels);
        MPPointD.recycleInstance(pix);
        return high;
    }

    void resetDraw(  Highlight highlight,IDataSet set,Entry e){
        MPPointD pix = getTransformer(set.getAxisDependency()).getPixelForValues(e.getX(), e.getY() * mAnimator
                .getPhaseY());
        highlight.setDraw((float) pix.x, (float) pix.y);
        MPPointD.recycleInstance(pix);
    }
    static class HighlightEntry{
        Highlight highlight;
        ILineDataSet dataSet;
        Entry entry;

        public HighlightEntry(Highlight highlight, ILineDataSet dataSet, Entry entry) {
            this.highlight = highlight;
            this.dataSet = dataSet;
            this.entry = entry;
        }
    }
    public void resetMinMaxHighlight(){
        LineData lineData = getData();
        if (lineData != null){
            int dataSetCount = lineData.getDataSetCount();
            if (dataSetCount >0){
                Entry minEntry = null;
                Entry maxEntry= null;
                Highlight tmpHighlight;
                for (int i =0;i<lineData.getDataSetCount();i++){
                    ILineDataSet dataSet = lineData.getDataSetByIndex(i);
                    IotLineDataSet set = ((IotLineDataSet)dataSet);
                    Entry tmpMin = set.getEntriesForYValue(dataSet.getYMin()).get(0);
                    Entry tmpMax = set.getEntriesForYValue(dataSet.getYMax()).get(0);
                    if (minEntry == null ||  (tmpMin.getY() < minEntry.getY())){
                        minEntry = tmpMin;
                        tmpHighlight = getHighlight(dataSet, minEntry, i);
                        minHighlight = new HighlightEntry(tmpHighlight, dataSet, minEntry);
                    }
                    if (maxEntry == null ||(tmpMax.getY() > maxEntry.getY())){
                        maxEntry = tmpMax;
                        tmpHighlight = getHighlight(dataSet, maxEntry, i);
                        maxHighlight = new HighlightEntry(tmpHighlight, dataSet, maxEntry);
                    }
                }
            }
        }
    }

    @Override
    protected void drawMarkers(Canvas canvas) {
        super.drawMarkers(canvas);
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (showMinMAxHighlight &&minHighlight !=null && maxHighlight != null ){
            resetDraw(minHighlight.highlight,minHighlight.dataSet, minHighlight.entry);
            resetDraw(maxHighlight.highlight,maxHighlight.dataSet, maxHighlight.entry);
            List<HighlightEntry> list =new ArrayList<HighlightEntry>();
            list.add(maxHighlight);
            list.add(minHighlight);

            for (int i = 0; i < list.size(); i++) {

                Highlight highlight = (Highlight) list.get(i).highlight;
                IDataSet set = mData.getDataSetByIndex(highlight.getDataSetIndex());

                Entry e = mData.getEntryForHighlight(highlight);
                if (e == null)
                    continue;

                int entryIndex = set.getEntryIndex(e);

                // make sure entry not null
                if (entryIndex > set.getEntryCount() * mAnimator.getPhaseX())
                    continue;

                float[] pos = getMarkerPosition(highlight);

                // check bounds
                if (!mViewPortHandler.isInBounds(pos[0], pos[1]))
                    continue;

                drawHighlightMarker(e, highlight,canvas, pos[0], pos[1]);
            }
        }
    }

    protected void drawHighlightMarker(Entry e, Highlight highlight, Canvas canvas, float po, float po1) {
        // callbacks to update the content
        if(mMarker != null){
            mMarker.refreshContent(e, highlight);
            // draw the marker
            mMarker.draw(canvas,po, po1);
        }

    }


    public IotLineChart(Context context) {
        super(context);
    }

    public IotLineChart(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public IotLineChart(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
}
